package us.gaaoc.framework.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.criterion.Restrictions;

import us.gaaoc.framework.model.Address;
import us.gaaoc.framework.model.AddressType;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.PersonAddress;

/**
 * @author Sukhada
 * 
 */
public class PersonAddressDAOHibernate extends
		GenericHibernateDAO<PersonAddress, String, PersonAddressDAO> implements
		PersonAddressDAO {

	public PersonAddress findPersonAddress(Person p, String addressUuid) {
		Query q = getSession().createQuery(
				"from PersonAddress pa where pa.person = ? and pa.address.uuid = ?");
		q.setEntity(0, p);
		q.setString(1, addressUuid);
		List result = q.list();
		if (result != null && !result.isEmpty()) {
			return (PersonAddress) result.get(0);
		} else
			return null;
	}
	
	public PersonAddress findPersonAddress(Person p) {
		Query q = getSession().createQuery(
				"from PersonAddress pa where pa.person = ?");
		q.setEntity(0, p);
		List result = q.list();
		if (result != null && !result.isEmpty()) {
			return (PersonAddress) result.get(0);
		} else
			return null;
	}
	
	/* (non-Javadoc)
	 * @see us.gaaoc.framework.dao.AddressDAO#findAddress(java.lang.String, us.gaaoc.framework.model.AddressType)
	 */
	public Address findAddress(Person person, AddressType addressType) {
		Address address = null;
		try {
			// eagerly fetch the AddressCategory object
			PersonAddress pa = (PersonAddress) getSession().createCriteria(PersonAddress.class)
				.setFetchMode("*", FetchMode.SELECT)
				.add(Restrictions.eq("person", person))
				.add(Restrictions.eq("addressType", addressType))
				.uniqueResult();
			if(pa != null) {
				address=pa.getAddress();
			}
		} catch (HibernateException e) {
			LOG.error(e);
			throw e;
		}
		return address;
	}
	/**
	 * Method to update the address association type of a person - address
	 * association.
	 * 
	 * @param addressUuid - UUID of address to updated
	 * @param addressType - Type of Address association to change to
	 * @return int statusCode <p>
	 *    <li> Status Codes
	 *    	<ul> 0 = Successful Execution
	 *      <ul> 1 = Error State
	 *   </li>
	 *   </p>
	 */
	public int updatePersonAddressType(String personAddressUuid, 
			AddressType addressType) {
		/* 
		 * Error Codes:
		 *  - 0 = Successful Execution
		 *  - 1 = Error State
		 */
		int outComeStatusCode = 1;
		String addressTypeUuid = addressType.getUuid();
		
		try {
			Query q = getSession().createSQLQuery(
					"UPDATE personAddress " 
						+ " SET addressTypeUuid = ?"
						+ " WHERE uuid = ?");
			q.setString(0, addressTypeUuid);
			q.setString(1, personAddressUuid);
			q.executeUpdate();
		} catch (HibernateException e) {
			outComeStatusCode = 1;
			LOG.error(e);
			throw e;
		}
		
		outComeStatusCode = 0;
		return outComeStatusCode;
	}

}
